iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
1
Security

資安0~100K只要30天系列 第 14

Day 14 - PHP 反序列化 (一)

  • 分享至 

  • xImage
  •  

對的你沒看錯
還是 PHP
就說它很香了

今天來講的是一個關於物件導向的高牆
其實這種反序列化漏洞不只在 PHP 有
還有偉大的 OOP 大宗 Java

什麼是物件導向

全名 Object-Oriented Programming
是具有物件概念的程式設計
可以包含資料、屬性、程式碼與函數等
整個架構中
就是以一個一個小物件堆疊而成
在 OOP 中有三個重要的概念
帶大家快速認識認識

封裝 Encapsulation

物件內部資源無法被直接使⽤
須經由物件提供的 "介⾯" 做存取

繼承 Inheritance

⼦類別可以繼承及覆寫⽗類別的變數、⽅法

多型 Polymorphism

使⽤同⼀抽象介⾯但以不同⽅式實作

什麼是序列化

在 OOP 中
程式語言如何將一個抽象的物件儲存下來呢
它會將這些抽象的物件轉換成一種固定格式的字串
用來描述該物件的一些特徵
以方便未來可以轉換回去做使用
這個行為就叫做序列化

在 php 中有兩個函數

serialize() <-> unserialize()

其功能就是

object <-> string

接下來的練習推薦大家可以去 PHP Sandbox 跟著一起動手看看

基本格式

class Test
{
    public $var = 'aaa';
};
$obj = new Test();
echo serialize($obj);

會輸出

最前面的 O 代表物件
而後面的 s 代表字串

要注意的是每一個變數都是由 名稱 + 值 的方式表達
那名稱跟值又會分別以 型態 + 數字 + 值 的格式

如果是物件
後面包的東西是用大括號,且結尾不需要分號

如果是一般變數
會以 名稱 + 分號 + 值 + 分號 的形式

PHP 中有其他種不同的型態
序列化後每一個都有它的代號

代號 意義
a array
b boolean
d double
i integer
o common object
r reference
s non-escaped string
C custom object
O class
N null
R pointer reference
S escaped string
U unicode string

特殊權限變數

在了解基本的序列化格式後
我們來看看在物件導向中的三種不同權限的變數

  • public
    • 所有人都可存取使用該變數
  • protected
    • 只有自己與繼承的類別可以使用
  • private
    • 只有自己可以使用

這三種變數在被 PHP 序列化出來後有非常特別的差異

class Test
{
    public $var = 123;
    protected $var2 = 123;
    private $var3 = 123;
};
echo serialize(new Test);

我們可以發現印出來的三種變數都呈現不一樣的表示方式

O:4:"Test":3:{s:3:"var";i:123;s:7:"*var2";i:123;s:10:"Testvar3";i:123;}

長這樣

權限 序列化後的字串
public s:3:"var";i:123;
protected s:7:"*var2";i:123;
private s:10:"Testvar3";i:123;

public 變數名稱沒有被特別的更動
protected 在變數名稱前面有用一個 * 跟著
private 會有 class 名稱被放在前綴

但這邊的 protected 與 private 有個小陷阱
其實在那個前綴的地方
都有一個 \x00 的字元包覆著

所以你用 sandbox 印出來會長這樣
出現一個問號的字元

所以正確的輸出應該是

權限 序列化後的字串
public s:3:"var";i:123;
protected s:7:"\0*\0var2";i:123;
private s:10:"\0Test\0var3";i:123;

上一篇
Day 13 - PHP 偽協議 (三)
下一篇
Day 15 - PHP 反序列化 (二)
系列文
資安0~100K只要30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言